package edu.vt.ece_3574.amber_alert.database;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.view.View;
import android.widget.ProgressBar;

import com.google.android.maps.GeoPoint;

import edu.vt.ece_3574.amber_alert.AmberAlertApplication;
import edu.vt.ece_3574.amber_alert.R;
import edu.vt.ece_3574.amber_alert.accounts.Account;
import edu.vt.ece_3574.amber_alert.location.LocationServerConnector;

public class DatabaseHandler {
	private static DatabaseHandler databaseHandler = new DatabaseHandler();
	
	public static final String databaseURL = "http://acorvin.no-ip.org:18080/";
	
	private DatabaseHandler() {
		
	}
	
	public static DatabaseHandler get() {
		return databaseHandler;
	}
	
	public String addAccountToServer(Account account) {
		try {
			return new AddAccountToServerHandler(account).execute().get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println();
		return null;
	}
	
	public Account getAccountFromServerByName(String name) {
		Account accountFromServer = null;
		try {
			accountFromServer = new GetAccountFromServerByNameHandler(name).execute().get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return accountFromServer;
	}
	
	public Account getAccountFromServerByNumber(String number) {
		Account accountFromServer = null;
		try {
			accountFromServer = new GetAccountFromServerByNumberHandler(number).execute().get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return accountFromServer;
	}
	
	public GeoPoint getLocationFromServer(Account account) {
		Account accountFromServer = null;
		try {
			accountFromServer = new GetAccountFromServerByNameHandler(account.getName()).execute().get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return accountFromServer.getLastLocation();
	}
	
	public Account checkLoginCredentials(String username, String password) {
		if (!determineIfUserExistsOnServer(username)) {
			return null;
		}
		
		Account accountFromServer = getAccountFromServerByName(username);
		if (accountFromServer.getPassword().equals(password)) {
			return accountFromServer;
		}
		
		return null;
	}
	
	public boolean determineIfUserExistsOnServer(String name) {
		try {
			return new DetermineIfUserExists(name).execute().get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public boolean determineIfUserExistsOnServer(Account account) {
		try {
			return new DetermineIfUserExists(account).execute().get();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public void updateAccountOnServer(Account account) {
		try {
			new UpdateAccountOnServer(account).execute();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public boolean phoneNumberIsPrimary(String number) {
		Account account = getAccountFromServerByNumber(number);
		return AmberAlertApplication.get().getCurrentAccount().getAssociatedAccounts().contains(account);
	}
	
	public void displayAccountLocation(Activity activity, final Account account) {
		ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.progressBar);
    	progressBar.setVisibility(View.VISIBLE);
    	
		Runnable locationServerConnector = new LocationServerConnector(account, "DisplayLocation", activity);
		Thread thread = new Thread(locationServerConnector);
		thread.start();
	}
	
	public void handleCurfewLocation(Activity activity, Account account) {
		Runnable locationServerConnector = new LocationServerConnector(account, "Curfew", activity);
		Thread thread = new Thread(locationServerConnector);
		thread.start();
	}
	
	/**
	 * Makes a call to the server to notify the specified account that the current account's location has been updated
	 * @param account the account to notify
	 */
	public void notifyAccountThisLocationIsUpdated(String account) {
		try {
			new NotifyServerLocationUpdated().execute(account).get();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Checks whether the phone has a valid internet connection
	 * @return whether an internet connection exists
	 */
	public boolean checkForInternetConnection() {
		ConnectivityManager conMgr = (ConnectivityManager) AmberAlertApplication.getContext().getSystemService (Context.CONNECTIVITY_SERVICE);
		if (conMgr.getActiveNetworkInfo() != null && conMgr.getActiveNetworkInfo().isAvailable() && conMgr.getActiveNetworkInfo().isConnected()) {
			return true;
		}
		else {
			return false;
		}
	}
}
